package ALDITS;
/*	
  *** Server.java ****
Copyright (c) 2008, Dan Crawford, Philip Nichols, Jacob Siegel, Tim Stefanski,
Justin Williamson All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of the Artemis Group nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

public class Server extends TimerTask{

	//Stories all socket connections
	private ArrayList<Socket> allClients; // ($ALDITS010)
	private Map game;
        private Timer timer;
        private boolean countdown;
        private int myCount;
	private TestbedServer spectator;
	
	public Server(){
		super();
		allClients=new ArrayList<Socket>();
		//Sets reference to server for all future listener threads
		ServerListenerThread.server=this;
		//timer=new Timer();
                spectator=new TestbedServer(this);
                spectator.setVisible(true);
                game = new Map(); // ($ALDITS0011)
		
		
	}
	public synchronized void processMessage(int clientID, String msg) {
		spectator.LogMsg(msg);
                String[] result = msg.split("~");
		if(result.length>0){
		String opCode=result[0];
		if(opCode.equals("hi")){
			//<Instantiate player object in game>
				sendMessage(clientID,game.addPlayer(result[1]));
                                sendMessage(-1,game.lobbyState());
				if (game.players.size()>=Map.maxPlayers){
					startUp();			
				}
		}
		else if(opCode.equals("leg")){
                        int endX = Integer.parseInt(result[1]);
                        int endY = Integer.parseInt(result[2]);
			for(Player p: game.players)
                            if(p.clientID==clientID)
                                p.nextLeg=new int[]{endX,endY};
		}
		else{
			
		}
			
		}
		
	}
	
	public synchronized void addClient(Socket s){
		allClients.add(s);
	}
	
	//Server creates new thread to listen on port 
	public void establishPresence(){
		new portListener().start();
	}
	
	//creates a new thread to listen on a specific client socket
	private void listen(Socket s){
		new ServerListenerThread(s).start();
	}
	
	public static void main(String[] args) {
        Server s= new Server();
       // s.establishPresence();

    }
        
        
	
	
	//Overloaded msg function
	public void sendMessage(int clientID, String msg){
		sendMessage(clientID,new String[] {msg});
	}
	
	//Send message in args to "clientID" client. Must already have a socket
	//connection. If clientID == -1 then message is sent to all clients
	public void sendMessage(int clientID, String[] args){
		if( clientID==-1){
			for(int i =0;i<allClients.size();i++)
				sendMessage(i,args);
			return;	
		}
		try {
			PrintWriter out = new PrintWriter(allClients.get(clientID).getOutputStream(), true);
			for(String msg:args)
				out.println(msg);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	//Thread class to listen on a port
	public class portListener extends Thread{
	
		public portListener(){
			super();
			
		}
		public void run(){
			ServerSocket serverSocket = null;
	        boolean listening = true;
	        try {
	            serverSocket = new ServerSocket(2123);
	        } catch (IOException e) {
	        	
	            System.err.println("Could not listen on port: 2123.");
	            System.err.println(e);
	            System.exit(-1);
	        }
	        try {
				while (listening){
				listen(serverSocket.accept());
				}

				serverSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

        public void startUp(){
        	timer = new Timer();
        	countdown=true;
        	myCount=10;
        	//assigns pos to planes
        	game.startGame();
        timer.schedule(this, 500,1000);
        }
    //Represents a single game-round
    public void run() {
    	//timer.schedule(this, 1000);
        //Its the final countdown....doo-daa-doo-doo
        if(countdown){
            sendMessage(-1,"go~"+(myCount--));
            if (myCount== 0)
                countdown=false;
        }else{
        //move players, find collisions, send messages
        
        //move objects
        game.update();
        //signal any victory
        if(!game.victoryMsg.equals("")){
            for(char c:game.victoryMsg.toCharArray())
                sendMessage(-1,"landed~"+c);
        }
        //signal team win
        int win=game.teamWinCheck();
        if(win!=-1)
            sendMessage(-1,"end~"+win);
        //send state to players
        for(int i=0;i<allClients.size();i++){
            sendMessage(i,game.personalize(i)); //($ALDITS005)
        
    }}
        }
    
        


}
